import { buffer2hex } from "@ctsy/buffer";
import { random } from "lodash";
import { Proto, Rule, Type } from ".";

function testRead() {
    let Rules: Rule[] = []
    let p = new Proto, ids: number[] = []
    for (let i = 0; i < 14; i++) {
        Rules.push(Object.assign(new Rule, {
            Type: i,
            ID: i + 1,
            Key: 'k' + i
        }))
        ids.push(i + 1)
    }
    p.Rules = Rules;
    p.Op = 0;
    p.Seq = 105
    let encoded = p.encode()
    // console.log('TestRead', buffer2hex(encoded))
    // console.log('TestRead', p.decode(encoded).map(z => z.ID).join() == ids.join())
}

function testWrite() {
    let Rules: Rule[] = []
    let p = new Proto, ids: number[] = [], id = 0
    for (let i = 0; i < 14; i++) {
        switch (i) {
            case Type.Int:
                Rules.push(Object.assign(new Rule, {
                    Type: i,
                    Len: 1,
                    ID: id++,
                    Key: 'k' + i
                }))
                Rules.push(Object.assign(new Rule, {
                    Type: i,
                    ID: id++,
                    Len: 2,
                    Key: 'k2t' + i
                }))
                Rules.push(Object.assign(new Rule, {
                    Type: i,
                    ID: id++,
                    Len: 4,
                    Key: 'k4t' + i
                }))
                p.Data['k' + i] = random(-50, 50)
                p.Data['k2t' + i] = random(-1024, 1024)
                p.Data['k4t' + i] = random(-8096 * 8, 8096 * 8)
                break;
            case Type.Float:
                Rules.push(Object.assign(new Rule, {
                    Type: i,
                    ID: id++,
                    Len: 4,
                    Key: 'Float'
                }))
                p.Data['Float'] = 0.25
                break
            case Type.Double:
                Rules.push(Object.assign(new Rule, {
                    Type: i,
                    ID: id++,
                    Len: 4,
                    Key: 'Double'
                }))
                p.Data['Double'] = 0.2515156
                break;
            case Type.Uint:
                Rules.push(Object.assign(new Rule, {
                    Type: i,
                    Len: 1,
                    ID: id++,
                    Key: 'k' + i
                }))
                Rules.push(Object.assign(new Rule, {
                    Type: i,
                    ID: id++,
                    Len: 2,
                    Key: 'k2t' + i
                }))
                Rules.push(Object.assign(new Rule, {
                    Type: i,
                    ID: id++,
                    Len: 4,
                    Key: 'k4t' + i
                }))
                p.Data['k' + i] = random(0, 255)
                p.Data['k2t' + i] = random(0, 65535)
                p.Data['k4t' + i] = random(0, 68835 * 8)
                break;
            case Type.FixString:
                Rules.push(Object.assign(new Rule, {
                    Type: i,
                    Len: 1,
                    ID: id++,
                    Key: 'k' + i
                }))
                Rules.push(Object.assign(new Rule, {
                    Type: i,
                    Len: 5,
                    ID: id++,
                    Key: 'k5t' + i
                }))
                Rules.push(Object.assign(new Rule, {
                    Type: i,
                    Len: 10,
                    ID: id++,
                    Key: 'k10t' + i
                }))
                p.Data['k' + i] = 'a'
                p.Data['k5t' + i] = '12345'
                p.Data['k10t' + i] = '12345'
                break;
            case Type.FixHex:
                Rules.push(Object.assign(new Rule, {
                    Type: i,
                    Len: 1,
                    ID: id++,
                    Key: 'k' + i
                }))
                Rules.push(Object.assign(new Rule, {
                    Type: i,
                    Len: 5,
                    ID: id++,
                    Key: 'k5t' + i
                }))
                Rules.push(Object.assign(new Rule, {
                    Type: i,
                    Len: 10,
                    ID: id++,
                    Key: 'k10t' + i
                }))
                p.Data['k' + i] = 'aa'
                p.Data['k5t' + i] = '0011223344'
                p.Data['k10t' + i] = '00112233440011223344'
                break;
            case Type.FixBase64:
                Rules.push(Object.assign(new Rule, {
                    Type: i,
                    Len: 1,
                    ID: id++,
                    Key: 'k' + i
                }))
                Rules.push(Object.assign(new Rule, {
                    Type: i,
                    Len: 5,
                    ID: id++,
                    Key: 'k5t' + i
                }))
                // Rules.push(Object.assign(new Rule, {
                //     Type: i,
                //     Len: 10,
                //     ID: id++,
                //     Key: 'k10t' + i
                // }))
                p.Data['k' + i] = 'YQ=='
                p.Data['k5t' + i] = 'YWJjZGU='
                // p.Data['k10t' + i] = '00112233440011223344'
                break;
            case Type.String:
                Rules.push(Object.assign(new Rule, {
                    Type: i,
                    Len: 5,
                    ID: id++,
                    Key: 'String' + i
                }))
                p.Data['String' + i] = "0123456789abcdajiofjwiofjojsfiwjoiefzjfiowjfioawe".slice(random(0, 10), random(10, 20))
                break;
            case Type.Hex:
                Rules.push(Object.assign(new Rule, {
                    Type: i,
                    Len: 5,
                    ID: id++,
                    Key: 'Hex' + i
                }))
                p.Data['Hex' + i] = "00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF".toLowerCase()
                break;
            case Type.Base64:
                Rules.push(Object.assign(new Rule, {
                    Type: i,
                    Len: 5,
                    ID: id++,
                    Key: 'Base64' + i
                }))
                p.Data['Base64' + i] = "YWJjZGU="
                break;
            case Type.SecendTime:
                Rules.push(Object.assign(new Rule, {
                    Type: i,
                    Len: 5,
                    ID: id++,
                    Key: 'Time' + i
                }))
                p.Data['Time' + i] = 1234567890
                break;
            case Type.MicroTime:
                Rules.push(Object.assign(new Rule, {
                    Type: i,
                    Len: 5,
                    ID: id++,
                    Key: 'MTime' + i
                }))
                p.Data['MTime' + i] = 1234567890
                break;
            default:
                break;
        }
        // ids.push(i + 1)
    }
    p.Rules = Rules;
    p.Op = 1;
    p.Seq = 1050
    let encoded = p.encode()
    // console.log('TestWrite', buffer2hex(encoded), JSON.stringify(p.Data))
    let de = new Proto()
    de.Rules = Rules;
    de.decode(encoded)
    // console.log('TestDecode', JSON.stringify(de.Data))
    if (JSON.stringify(p.Data) == JSON.stringify(de.Data)) {
        // console.warn('成功')
        console.log(JSON.stringify(p.Data))
        console.log(encoded.toString('hex'))
    } else {
        console.warn("失败", JSON.stringify(p.Data))
        for (let k in p.Data) {
            if (p.Data[k] != de.Data[k]) {
                console.log('\t', k, p.Data[k], de.Data[k])
            }
        }
        process.exit(0)
    }
}

function test() {
    // testRead()
    for (let i = 0; i < 10; i++) {
        // console.log('test', i)
        testWrite()
    }
}

test()